﻿using AutoMapper;
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Cmp;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Infrastructure.ApllicationDto;
using Zocono.WCS.Infrastructure.ApllicationDto.Enums;
using Zocono.WCS.Infrastructure.ApllicationDto.WCSTaskDto;
using Zocono.WCS.Infrastructure.BaseRepository.SqlSugarUtil;
using Zocono.WCS.WMSApiDomain.WebApi;

namespace Zocono.WCS.Domain.WorkTaskDomain
{
    public class HistoryWorkTaskInfoServeice : IHistoryWorkTaskInfoServeice
    {
        private readonly ILogUtil _LogUtil;
        private readonly ISnowflake _Sonoflake;
        private readonly IHistoryWorkTaskInfoRepository _HistoryWorkTaskInfoRepository;
        private readonly IMapper _mapper;

        public HistoryWorkTaskInfoServeice(ILogUtil logUtil
            , ISnowflake snowflake
            , IHistoryWorkTaskInfoRepository historyWorkTaskInfoRepository
            , IMapper mapper)
        {
            _LogUtil = logUtil;
            _Sonoflake = snowflake;
            _HistoryWorkTaskInfoRepository = historyWorkTaskInfoRepository;
            _mapper = mapper;
        }

        public async Task<bool> BackSetTaskAsync(long id)
        {
            try
            {
                //查询出历史任务数据
                var historyInfo = await _HistoryWorkTaskInfoRepository.GetByIdAsync(id);
                if (historyInfo != null)
                {
                    var workTaskInfo = _mapper.Map<HistoryWorkTaskInfo, WorkTaskInfo>(historyInfo);
                    if (workTaskInfo != null)
                    {
                        //还原回去任务默认为执行中，依据实际情况在任务列表修改任务状态
                        workTaskInfo.TaskState = EnumTaskState.Executing;
                        workTaskInfo.CurrentDetailTaskState = EnumDetailTaskState.Executing;
                    }
                    await _HistoryWorkTaskInfoRepository.AsSugarClient().ExecTranAsync<bool>(async () =>
                    {
                        await _HistoryWorkTaskInfoRepository.AsSugarClient().Insertable(workTaskInfo).ExecuteCommandAsync();
                        await _HistoryWorkTaskInfoRepository.AsSugarClient().Deleteable(historyInfo).ExecuteCommandAsync();
                        return true;
                    });
                    return true;
                    //try
                    //{
                    //    _HistoryWorkTaskInfoRepository.AsSugarClient().AsTenant().BeginTran();

                    //    await _HistoryWorkTaskInfoRepository.AsSugarClient().Insertable(workTaskInfo).ExecuteCommandAsync();
                    //    await _HistoryWorkTaskInfoRepository.AsSugarClient().Deleteable(historyInfo).ExecuteCommandAsync();

                    //    _HistoryWorkTaskInfoRepository.AsSugarClient().AsTenant().CommitTran();
                    //    return true;
                    //}
                    //catch (Exception)
                    //{
                    //    _HistoryWorkTaskInfoRepository.AsSugarClient().AsTenant().RollbackTran();
                    //    throw;
                    //}
                }
                return false;
            }
            catch (Exception ex)
            {
                _LogUtil.Error($"还原任务报错ex={ex.ToString()}");
                return false;
            }
        }

        public async Task<PageDto<HistoryWorkTaskInfoDto>> GetPagedCurrentWorkTaskInfoAsync(QueryHistoryWorkTaskInfoDto queryWorkTaskInfoDto)
        {
            var exp = Expressionable.Create<HistoryWorkTaskInfo, RouteInfo>();

            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.PalletCode), (wti, ri) => wti.PalletCode.Contains(queryWorkTaskInfoDto.PalletCode));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.RouteInfo), (wti, ri) => ri.FromStation.Contains(queryWorkTaskInfoDto.RouteInfo) || ri.ToStation.Contains(queryWorkTaskInfoDto.RouteInfo));

            exp.AndIF(queryWorkTaskInfoDto.TaskCode.HasValue, (wti, ri) => wti.TaskCode == queryWorkTaskInfoDto.TaskCode);
            if (queryWorkTaskInfoDto.TaskState > 2)
            {
                exp.AndIF(true, (wti, ri) => wti.TaskState == EnumTaskState.Executing || wti.TaskState == EnumTaskState.Initial);
            }
            else if (queryWorkTaskInfoDto.TaskState == null)
            {
                exp.AndIF(true, (wti, ri) => wti.TaskState == EnumTaskState.Executing || wti.TaskState == EnumTaskState.Initial);
            }
            else if (queryWorkTaskInfoDto.TaskState == 2)
            {
                exp.AndIF(true, (wti, ri) => wti.TaskState == EnumTaskState.Executing);
            }
            else if (queryWorkTaskInfoDto.TaskState == 0)
            {
                exp.AndIF(true, (wti, ri) => wti.TaskState == EnumTaskState.Initial);
            }
            else
            {
                exp.AndIF(queryWorkTaskInfoDto.TaskState.HasValue, (wti, ri) => wti.TaskState.ToInt32() == queryWorkTaskInfoDto.TaskState);
            }

            PageDto<HistoryWorkTaskInfoDto> pagedData = new PageDto<HistoryWorkTaskInfoDto>();
            RefAsync<int> totalCount = 0;

            var result = await _HistoryWorkTaskInfoRepository.AsSugarClient()
                .Queryable<HistoryWorkTaskInfo, RouteInfo>((wti, ri) => new JoinQueryInfos(JoinType.Inner, wti.RouteID == ri.ID))
                .Where(exp.ToExpression())
                .Select((wti, ri) => new HistoryWorkTaskInfoDto()
                {
                    ID = wti.ID,
                    RouteID = wti.RouteID,
                    FromStation = ri.FromStation,
                    ToStation = ri.ToStation,
                    Priority = wti.Priority,
                    PalletCode = wti.PalletCode,
                    TaskCode = wti.TaskCode,
                    TaskProcessState = wti.TaskProcessState,
                    TaskState = wti.TaskState,
                    TaskType = wti.TaskType,
                    SaveTime = wti.SaveTime,
                    UpdateTime = wti.UpdateTime,
                    WmsTaskCode = wti.WmsTaskCode,
                    DependWmsTaskCode = wti.DependWmsTaskCode,
                    WmsFromStation = wti.WmsFromStation,
                    WmsFromPosition = wti.WmsFromPosition.ToString(),
                    WmsToStation = wti.WmsToStation,
                    WmsToPosition = wti.WmsToPosition,
                    CurrentRounteDetailID = wti.CurrentRounteDetailID,
                    CurrentDetailTaskState = wti.CurrentDetailTaskState,
                    CurrentDispatchType = wti.CurrentDispatchType,
                    CurrentFromEquipment = wti.CurrentFromEquipment,
                    CurrentFromCargo = wti.CurrentFromCargo,
                    CurrentToEquipment = wti.CurrentToEquipment,
                    CurrentToCargo = wti.CurrentToCargo,
                    CurrentCreateTime = wti.CurrentCreateTime,
                    CurrentUpdateTime = wti.CurrentUpdateTime,
                    UploadWmsState = wti.UploadWmsState,
                    UploadWmsTime = wti.UploadWmsTime
                })
                .ToPageListAsync(queryWorkTaskInfoDto.PageIndex, queryWorkTaskInfoDto.PageSize, totalCount);

            pagedData.Result = result;
            pagedData.Total = totalCount;

            return pagedData;
        }


        public async Task<PageDto<HistoryWorkTaskInfoDto>> GetPagedWorkTaskInfoAsync(QueryHistoryWorkTaskInfoDto queryWorkTaskInfoDto)
        {
            var exp = Expressionable.Create<HistoryWorkTaskInfo, RouteInfo>();

            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.PalletCode), (wti, ri) => wti.PalletCode.Contains(queryWorkTaskInfoDto.PalletCode));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.StarTime), (wti, ri) => wti.SaveTime >= queryWorkTaskInfoDto.StarTime.ToDateTimeFormat("yyyy-MM-dd HH:mm"));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.EndTime), (wti, ri) => wti.SaveTime < queryWorkTaskInfoDto.EndTime.ToDateTimeFormat("yyyy-MM-dd HH:mm"));

            exp.AndIF(queryWorkTaskInfoDto.UploadWmsState.HasValue, (wti, ri) => wti.UploadWmsState == Enum.Parse<EnumUploadWmsState>(queryWorkTaskInfoDto.UploadWmsState.ToString()));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.FromStation), (wti, ri) => ri.FromStation.Contains(queryWorkTaskInfoDto.FromStation));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.ToStation), (wti, ri) => ri.ToStation.Contains(queryWorkTaskInfoDto.ToStation));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.RouteInfo), (wti, ri) => ri.FromStation.Contains(queryWorkTaskInfoDto.RouteInfo) || ri.ToStation.Contains(queryWorkTaskInfoDto.RouteInfo));
            

            exp.AndIF(queryWorkTaskInfoDto.Priority.HasValue, (wti, ri) => wti.Priority == queryWorkTaskInfoDto.Priority);
            exp.AndIF(queryWorkTaskInfoDto.CurrentDispatchType!=0, (wti, ri) =>(int) wti.CurrentDispatchType == queryWorkTaskInfoDto.CurrentDispatchType);
            exp.AndIF(queryWorkTaskInfoDto.TaskCode.HasValue, (wti, ri) => wti.TaskCode == queryWorkTaskInfoDto.TaskCode);
            exp.AndIF(queryWorkTaskInfoDto.TaskProcessState.HasValue, (wti, ri) => wti.TaskProcessState == Enum.Parse<EnumTaskProcessState>(queryWorkTaskInfoDto.TaskProcessState.ToString()));

            exp.AndIF(queryWorkTaskInfoDto.TaskState.HasValue, (wti, ri) => wti.TaskState == Enum.Parse<EnumTaskState>(queryWorkTaskInfoDto.TaskState.ToString()));
            exp.AndIF(queryWorkTaskInfoDto.TaskType.HasValue, (wti, ri) => wti.TaskType == Enum.Parse<EnumTaskType>(queryWorkTaskInfoDto.TaskType.ToString()));

            exp.AndIF(queryWorkTaskInfoDto.FromSaveTime.HasValue && queryWorkTaskInfoDto.ToSaveTime.HasValue, (wti, ri) => wti.SaveTime >= queryWorkTaskInfoDto.FromSaveTime && wti.SaveTime < queryWorkTaskInfoDto.ToSaveTime);
            exp.AndIF(queryWorkTaskInfoDto.FromUpdateTime.HasValue && queryWorkTaskInfoDto.ToUpdateTime.HasValue, (wti, ri) => wti.UpdateTime >= queryWorkTaskInfoDto.FromUpdateTime && wti.UpdateTime < queryWorkTaskInfoDto.ToUpdateTime);

            exp.AndIF(queryWorkTaskInfoDto.WmsTaskCode.HasValue, (wti, ri) => wti.WmsTaskCode == queryWorkTaskInfoDto.WmsTaskCode);
            exp.AndIF(queryWorkTaskInfoDto.DependWmsTaskCode.HasValue, (wti, ri) => wti.DependWmsTaskCode == queryWorkTaskInfoDto.DependWmsTaskCode);
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.WmsFromStation), (wti, ri) => wti.WmsFromStation.Contains(queryWorkTaskInfoDto.WmsFromStation));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.WmsFromPosition), (wti, ri) => wti.WmsFromPosition.ToString().Contains(queryWorkTaskInfoDto.WmsFromPosition));

            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.WmsToStation), (wti, ri) => wti.WmsToStation.Contains(queryWorkTaskInfoDto.WmsToStation));
            exp.AndIF(!string.IsNullOrEmpty(queryWorkTaskInfoDto.WmsToPosition), (wti, ri) => wti.WmsToPosition.Contains(queryWorkTaskInfoDto.WmsToPosition));

            PageDto<HistoryWorkTaskInfoDto> pagedData = new PageDto<HistoryWorkTaskInfoDto>();
            RefAsync<int> totalCount = 0;

            var result = await _HistoryWorkTaskInfoRepository.AsSugarClient()
                .Queryable<HistoryWorkTaskInfo, RouteInfo>((wti, ri) => new JoinQueryInfos(JoinType.Inner, wti.RouteID == ri.ID))
                .Where(exp.ToExpression())
                .OrderBy((wti, ri) => wti.SaveTime, OrderByType.Desc)
                .Select((wti, ri) => new HistoryWorkTaskInfoDto()
                {
                    ID = wti.ID,
                    RouteID = wti.RouteID,
                    FromStation = ri.FromStation,
                    ToStation = ri.ToStation,
                    Priority = wti.Priority,
                    PalletCode = wti.PalletCode,
                    TaskCode = wti.TaskCode,
                    TaskProcessState = wti.TaskProcessState,
                    TaskState = wti.TaskState,
                    TaskType = wti.TaskType,
                    SaveTime = wti.SaveTime,
                    UpdateTime = wti.UpdateTime,
                    WmsTaskCode = wti.WmsTaskCode,
                    DependWmsTaskCode = wti.DependWmsTaskCode,
                    WmsFromStation = wti.WmsFromStation,
                    WmsFromPosition = wti.WmsFromPosition.ToString(),
                    WmsToStation = wti.WmsToStation,
                    WmsToPosition = wti.WmsToPosition,
                    CurrentRounteDetailID = wti.CurrentRounteDetailID,
                    CurrentDetailTaskState = wti.CurrentDetailTaskState,
                    CurrentDispatchType = wti.CurrentDispatchType,
                    CurrentFromEquipment = wti.CurrentFromEquipment,
                    CurrentFromCargo = wti.CurrentFromCargo,
                    CurrentToEquipment = wti.CurrentToEquipment,
                    CurrentToCargo = wti.CurrentToCargo,
                    CurrentCreateTime = wti.CurrentCreateTime,
                    CurrentUpdateTime = wti.CurrentUpdateTime,
                    UploadWmsState = wti.UploadWmsState,
                    UploadWmsTime = wti.UploadWmsTime
                })
                .ToPageListAsync(queryWorkTaskInfoDto.PageIndex, queryWorkTaskInfoDto.PageSize, totalCount);

            pagedData.Result = result;
            pagedData.Total = totalCount;

            return pagedData;
        }

        public Task<HistoryWorkTaskInfo> GetWorkTaskInfoByIdAsync(long id)
        {
            throw new NotImplementedException();
        }

        public async Task<bool> InsertHistoyWorkTaskInfoAsync(HistoryWorkTaskInfoDto historyWorkTaskInfoDto)
        {
            try
            {
                var historyWorkTaskInfo = _mapper.Map<HistoryWorkTaskInfoDto, HistoryWorkTaskInfo>(historyWorkTaskInfoDto);
                return await _HistoryWorkTaskInfoRepository.InsertAsync(historyWorkTaskInfo);
            }
            catch (Exception ex)
            {
                _LogUtil.Error($"添加数据历史任务数据库报错ex={ex.ToString()}");
                return false;
            }
        }
    }
}
